﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Tanis.RouteService;
using System.IO.IsolatedStorage;
using System.Globalization;
using System.Threading;

namespace Tanis.Settings
{
    public partial class SettingsControl : UserControl
    {
        #region Contructor
        public SettingsControl()
        {
            _language = new Dictionary<string, string>();
            _language.Add("English", "en-US");
            _language.Add("Lietuvių", "lt-LT");
            _language.Add("Русский", "ru-RU");

            _initializing = true;
            InitializeComponent();

            this.lpkLanguage.ItemsSource = _language.Keys;
            this.lpkLanguage.SelectedItem = _language.FirstOrDefault(x => x.Value == GetApplicationLanguage()).Key;

            App.ViewModel.CityListLoaded += ViewModel_CityListLoaded;

            if (App.ViewModel.IsDataLoaded)
            {
                ViewModel_CityListLoaded(null, null);
            }
        }
        #endregion

        #region Properties
        private Dictionary<string, string> _language;
        private volatile bool _initializing;
        public const string INIT_DEFAULT_CITY = "vilnius";
        public event EventHandler LanguageChanged;

        /// <summary>
        /// Returns string array of available cities/locations
        /// </summary>
        public static List<ScopeInfo> CityList
        {
            get
            {
                return App.ViewModel.Cities.ToList();
            }
        }

        /// <summary>
        /// Application default city for transportation routes
        /// </summary>
        public static string DefaultCity
        {
            get
            {
                string defaultCity = GetApplicationSetting("DefaultCity") as string;

                if (defaultCity != null)
                {
                    return defaultCity;
                }

                return INIT_DEFAULT_CITY;
            }
            set
            {
                SetApplicationSetting("DefaultCity", value);
            }
        }

        #endregion
        
        #region Read / write settings to Phone memory

        /// <summary>
        /// Reads application data from persistent storage
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public static object GetApplicationSetting(string settingName)
        {
            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

            if (settings.Contains(settingName))
            {
                return settings[settingName];
            }

            return null;
        }

        /// <summary>
        /// Saves application data to persistent storage
        /// </summary>
        /// <param name="settingName"></param>
        /// <param name="value"></param>
        public static void SetApplicationSetting(string settingName, object value)
        {
            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

            if (settings.Contains(settingName))
            {
                settings[settingName] = value;
            }
            else
            {
                settings.Add(settingName, value);
            }

            settings.Save();
        }

        #endregion

        #region Functions for updating interface language dynamically
        /// <summary>
        /// Updates interaface language to one specified in settings
        /// </summary>
        public static void UpdateInterafaceLanguage()
        {
            string language = GetApplicationSetting("Language") as string;

            if (language == null)
            {
                language = "en-US";
            }

            CultureInfo culture = new CultureInfo(language);

            UpdateInterafaceLanguage(culture);
        }

        /// <summary>
        /// Updates interface language
        /// </summary>
        /// <param name="newCulture"></param>
        public static void UpdateInterafaceLanguage(CultureInfo newCulture)
        {
            Thread.CurrentThread.CurrentUICulture = newCulture;
            Thread.CurrentThread.CurrentCulture = newCulture;

            SetApplicationSetting("Language", newCulture.Name);
            ((LocalizedStrings)App.Current.Resources["LocalizedStrings"]).ResetResources();
        }

        private string GetApplicationLanguage()
        {
            string language = GetApplicationSetting("Language") as string;

            if (language != null)
            {
                return language;
            }

            return "en-US";
        }
        #endregion

        #region Event handlers for settings
        /// <summary>
        /// Updates interface language based on user selection
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lpkLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 0 || _initializing)
            {
                return;
            }

            string selectedLanguage = e.AddedItems[0].ToString();
            CultureInfo selectedCulture = new CultureInfo(_language[selectedLanguage]);

            UpdateInterafaceLanguage(selectedCulture);

            // update setting page labels manually because they are not reloaded automatically after language change //
            lpkLanguage.Header = Localization.LocalizedStringsRes.SettingsLabelLanguage;
            lpkDefaultCity.Header = Localization.LocalizedStringsRes.SettingsLabelDefaultCity;

            if (LanguageChanged != null)
            {
                LanguageChanged(null, null);
            }
        }

        /// <summary>
        /// Updates default city based on user selection
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lpkDefaultCity_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 0 || _initializing)
            {
                return;
            }

            string selectedDefaultCity = ((ScopeInfo)e.AddedItems[0]).Folder;

            DefaultCity = selectedDefaultCity;
            MainPage.MainPageInstance._pivot.Title = DefaultCity.ToUpper();
            App.ViewModel.LoadStopList();
        }

        void ViewModel_CityListLoaded(object sender, EventArgs e)
        {
            _initializing = true;

            lpkDefaultCity.ItemsSource = CityList;

            string selectedCity = DefaultCity;
            var selectedItem = CityList.FirstOrDefault(s => s.Folder == selectedCity);
            lpkDefaultCity.SelectedItem = selectedItem ?? CityList[0];

            _initializing = false;
        }
        #endregion
    }
}
